Náhodná pozice v kruhu

(publikováno 30.05.2017) PHP, JavaScript, Tipy & triky

Jak vygenerovat pozici bodu v kruhu, tak aby bylo rozprostření uniformní? Je to velmi jednoduchý výpočet, musí být ale proveden správně.

Náhodná pozice v kruhu

Vygenerovat náhodnou pozici ve čtverci, nebo obdélníku není nic těžkého. Stačí určit 2 náhodná čísla v rozsahu <0; w> pro šířku a <0; h> pro výšku a je to. Určení v kruhu je už ale komplikovanější, pokud mají být všechny pozice obsazovány se stejnou pravděpodobností.

Náhodný poloměr a úhel

Celý princip spočívá ve vygenerování dvou náhodný čísel v rozsahu <0; 1), kde větší číslo určí poloměr kružnice, na které bude bod ležet. Menší číslo pak v poměru s větším určuje úhel natočení, tj. 1 bod na získané kružnici. Pozice v kruhu se získají pomocí následující rovnice, kde r značí poloměr výsledného kruhu.

Rovnice

Nutnou podmínkou pro uniformní rozložení bodů je prohození hodnot a a b, pokud je b < a, neboli b musí být vždy větší nebo rovno a.

Simulátor

Na stránce testdata.kutac.cz je připraven testovací skript s vizualizací generovaných bodů. Lze si také otestovat, přípar kdy se hodnoty a a b nebudou prohazovat (více bodů bude uprostřed kruhu), nebo se prohodí pokud je a < b, tím pádem a bude vždy větší (vznikne šnek).

Body na kružnici

Pokud je potřeba generovat body pouze na kružnici, nikoli v kruhu, stačí hodnotu b odebrat z rovnice, případně ji nastavit na 1. Poté budou body umístěny pouze na obvodu.

Kód

Implementaci je nutné přizpůsobit jazyku tak, aby generoval náhodná čísla v rozmezí <0; 1), což JavaScript splňuje.

function getCircleRandomPosition(radius){
    a = Math.random();
    b = Math.random();
    var ret = {
        x: 0,
        y: 0
    }
    if (a > 0 || b > 0) {
        if (b < a) {
            var x = a;
            a = b;
            b = x;
        }
        ret.x = radius * b * Math.cos(2 * Math.PI * a/b);
        ret.y = radius * b * Math.sin(2 * Math.PI * a/b);
    }
    return ret;
}

V PHP, podobně jako v C/C++, je náhodné číslo celočíselné. Jednoduchý převod z celého čísla na reálné číslo do rozsahu 0 (včetně) až 1 (bez) je:

$randomNumber = mt_rand(0, mt_getrandmax() - 1) / mt_getrandmax();

Generování pomocí rovnice kružnice a koule

Tento přístup není úplně vhodný pro větší množství bodů, je ale také možné jej použít. Navíc je stejným způsobem možné generovat také body v 3D kouli. Rovnice kružnice je x^2 + y^2 = r^2 a nyní stačí vygenerovat náhodné x a y. Pokud výsledné r vyjde větší než poloměr kruhu, stačí náhodná čísla zahodit a vygenerovat znova. Pro kouli je postup totožný, pouze se do rovnice přidá navíc souřadnice z.


S podobnými zkušenostmi s generováním náhodné hodnoty na ploše můžete sdílet v komentářích. Úvodní fotka převzata z Freepik.com

K tomuto článku již není možné přidávat další komentáře